package com.larly.service.impl;

import cn.hutool.core.util.ObjUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.larly.common.PageRequest;
import com.larly.exception.ErrorCode;
import com.larly.exception.ThrowUtils;
import com.larly.model.domain.User;
import com.larly.model.domain.UserFollow;
import com.larly.model.dto.userfollow.UserFollowAddRequest;
import com.larly.model.vo.UserVO;
import com.larly.service.NotificationService;
import com.larly.service.UserFollowService;
import com.larly.mapper.UserFollowMapper;
import com.larly.service.UserService;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.stream.Collectors;

/**
* @author 许颢达
* @description 针对表【user_follow(用户关注关系表)】的数据库操作Service实现
* @createDate 2025-08-22 19:42:05
*/
@Service
public class UserFollowServiceImpl extends ServiceImpl<UserFollowMapper, UserFollow>
    implements UserFollowService{

    @Resource
    @Lazy
    private UserService userService;

    @Resource
    private NotificationService notificationService;

    /**
     * 关注
     * @param userFollowAddRequest
     * @param request
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean follow(UserFollowAddRequest userFollowAddRequest, HttpServletRequest request) {
        ThrowUtils.throwIf(ObjUtil.isNull(userFollowAddRequest), ErrorCode.PARAM_ERROR);

        Integer followerId = userFollowAddRequest.getFollowerId();
        ThrowUtils.throwIf(ObjUtil.isNull(followerId) || followerId <= 0, ErrorCode.PARAM_ERROR, "关注者ID不能为空");

        Integer followingId = userFollowAddRequest.getFollowingId();
        ThrowUtils.throwIf(ObjUtil.isNull(followingId) || followingId <= 0, ErrorCode.PARAM_ERROR,"被关注者ID不能为空");

        // 判断是否已关注
        QueryWrapper<UserFollow> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("follower_id", followerId).eq("following_id", followingId);
        if (count(queryWrapper) > 0) {
            // 已关注
            return false;
        }
        // 判断用户是否存在
        User userFollowing = userService.getById(followingId);
        ThrowUtils.throwIf(ObjUtil.isNull(userFollowing), ErrorCode.RESOURCE_NOT_FOUND,"被关注用户不存在");
        User userFollower = userService.getById(followerId);
        ThrowUtils.throwIf(ObjUtil.isNull(userFollower), ErrorCode.RESOURCE_NOT_FOUND, "本人不存在");


        // 添加关注
        UserFollow userFollow = new UserFollow();
        userFollow.setFollowerId(followerId);
        userFollow.setFollowingId(followingId);
        boolean save = save(userFollow);
        ThrowUtils.throwIf(!save, ErrorCode.SYSTEM_ERROR, "关注失败");

        // 添加关注通知
        if (userFollowing != null && userFollower != null){
            notificationService.triggerFollowNotify(followerId, followingId);
        }

        return true;
    }

    @Override
    public boolean unfollow(UserFollowAddRequest userFollowAddRequest, HttpServletRequest request) {
        ThrowUtils.throwIf(ObjUtil.isNull(userFollowAddRequest), ErrorCode.PARAM_ERROR);

        Integer followerId = userFollowAddRequest.getFollowerId();
        ThrowUtils.throwIf(ObjUtil.isNull(followerId) || followerId <= 0, ErrorCode.PARAM_ERROR, "关注者ID不能为空");

        Integer followingId = userFollowAddRequest.getFollowingId();
        ThrowUtils.throwIf(ObjUtil.isNull(followingId) || followingId <= 0, ErrorCode.PARAM_ERROR,"被关注者ID不能为空");

        QueryWrapper<UserFollow> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("follower_id", followerId).eq("following_id", followingId);
        boolean remove = remove(queryWrapper);
        ThrowUtils.throwIf(!remove, ErrorCode.SYSTEM_ERROR, "取消关注失败");
        return false;
    }

    /**
     * 获取粉丝
     * @param request
     * @param pageRequest
     * @return
     */
    @Override
    public List<UserVO> getFollower(HttpServletRequest request, PageRequest pageRequest) {
        User loginUser = userService.getLoginUser(request);
        Page<UserFollow> userFollowPage = this.lambdaQuery()
                .eq(UserFollow::getFollowingId, loginUser.getId())
                .page(new Page<>(pageRequest.getPageNum(), pageRequest.getPageSize()));
        return userFollowPage.getRecords().stream().map(userFollow -> {
            User user = userService.getById(userFollow.getFollowerId());
            return UserVO.toVO(user);
        }).collect(Collectors.toList());
    }

    /**
     * 获取关注
     * @param request
     * @param pageRequest
     * @return
     */
    @Override
    public List<UserVO> getFollowing(HttpServletRequest request, PageRequest pageRequest) {
        User loginUser = userService.getLoginUser(request);
        Page<UserFollow> userFollowPage = this.lambdaQuery()
                .eq(UserFollow::getFollowerId, loginUser.getId())
                .page(new Page<>(pageRequest.getPageNum(), pageRequest.getPageSize()));
        return userFollowPage.getRecords().stream().map(userFollow -> {
            User user = userService.getById(userFollow.getFollowingId());
            return UserVO.toVO(user);
        }).collect(Collectors.toList());
    }
}




